home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 21 / CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso / CUCD / Programming / Python-1.4 / Source / Amiga / Python_netlib / _chkufb.c < prev    next >
C/C++ Source or Header  |  1996-11-16  |  3KB  |  156 lines

  1. RCS_ID_C="$Id: _chkufb.c,v 4.1 1994/09/29 23:09:02 jraja Exp $";
  2. /*
  3.  *      _chkufb.c - return struct ufb * from a file handle (SAS/C)
  4.  *
  5.  *      Copyright © 1994 AmiTCP/IP Group, 
  6.  *                       Network Solutions Development Inc.
  7.  *                       All rights reserved.
  8.  */
  9.  
  10. #include <ios1.h>
  11. #include <stdlib.h>
  12. #include <errno.h>
  13. #include <bsdsocket.h>
  14. #include <sys/cdefs.h>
  15. #include <amitcp/socketbasetags.h>
  16. #include <syslog.h>
  17. #include "libcheck.h"
  18.  
  19. extern unsigned long __fmask;
  20. extern int (*__closefunc)(int);
  21.  
  22. long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
  23.  
  24. /*
  25.  * The initializator priority is just above the standard I/O, so that this
  26.  * will be called after the standard I/O is initialized
  27.  */
  28. long __stdargs
  29. _STI_510_install_AmiTCP_callback(void)
  30. {
  31.   /* needs bsdsocket.library -- I.J. */
  32.   if(checkbsdsocketlib())
  33.   {
  34.     if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
  35.     syslog(LOG_ERR, "Cannot install fdCallback!");
  36.  
  37. #if __VERSION__ > 6 || __REVISION__ > 3
  38.     return 1;
  39. #else
  40.     exit(20);
  41. #endif
  42.     }
  43.   }
  44.   else PyErr_Clear();             /* don't report error if socketlib not found */
  45.  
  46.   /*
  47.    * Set up __closefunc (which is used at stdio cleanup)
  48.    */
  49.   __closefunc = __close;
  50.  
  51.   /*
  52.    * Set default file mask to UNIX style
  53.    */
  54.   __fmask = 0644; 
  55.  
  56.   return 0;
  57. }
  58.  
  59. long ASM SAVEDS
  60. fdCallback(REG(d0) int fd, REG(d1) int action)
  61. {
  62.   struct UFB *ufb;
  63.   int fd2;
  64.  
  65. #ifdef DEBUG
  66.   syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
  67. #endif
  68.  
  69.   switch (action) {
  70.   case FDCB_FREE:
  71.     ufb = __chkufb(fd);
  72.     if (ufb == NULL)
  73.       return EBADF;
  74.  
  75.     if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
  76. #ifdef DEBUG
  77.       syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
  78. #endif
  79.       return ENOTSOCK;
  80.     }
  81.  
  82.     ufb->ufbflg = 0;
  83.     return 0;
  84.  
  85.   case FDCB_ALLOC:
  86.     do {
  87.       ufb = __allocufb(&fd2);
  88.       if (ufb == NULL)
  89.     return ENOMEM;
  90. #ifdef DEBUG
  91.       if (fd2 > fd) {
  92.     syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
  93.     return EINVAL;
  94.       }
  95. #endif
  96.       ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
  97.       ufb->ufbfh = NULL; /* no file handle */
  98.       ufb->ufbfn = NULL; /* no name */
  99.     } while (fd2 < fd);
  100.     return 0;
  101.  
  102.   case FDCB_CHECK:
  103.     ufb = __chkufb(fd);
  104.     if (ufb != NULL && ufb->ufbflg != 0) 
  105.       return EBADF;
  106.     
  107.     return 0;
  108.  
  109.   default:
  110. #ifdef DEBUG
  111.     syslog(LOG_ERR, "fdCallback: invalid action.");
  112. #endif
  113.     return EINVAL;
  114.   }
  115. }
  116.  
  117.  
  118. struct UFB *
  119. __chkufb(int fd)
  120. {
  121.   struct UFB *ufb;
  122.  
  123.   /* a single element cache */
  124.   static struct UFB *last_ufb = NULL;
  125.   static int         last_fd = -1;
  126.  
  127.   _OSERR = 0;
  128.  
  129.   if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
  130.     errno = EBADF;
  131.     return NULL;
  132.   }
  133.  
  134.   /*
  135.    * Check the cache first
  136.    */
  137.   if (fd == last_fd)
  138.     return last_ufb;
  139.  
  140.   last_fd = fd; /* update cache */
  141.   ufb = __ufbs;
  142.   while (fd > 0 && ufb != NULL) {
  143.     fd--;
  144.     ufb = ufb->ufbnxt;
  145.   }
  146.   last_ufb = ufb; /* update cache */
  147.   
  148.   if (ufb == NULL) {
  149.     last_fd = -1; /* invalidate cache */
  150.     errno = EIO;
  151.     return NULL;
  152.   }
  153.   else
  154.     return ufb;
  155. }
  156.